package org.advanced.aqs;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author John.zhang
 * @version Id: Conditions, v 1.0 2020/12/11 10:41 ZhiYong Exp $
 */
public class Conditions {

    public static void main(String[] args) throws InterruptedException {
        ReentrantLock reentrantLock = new ReentrantLock();
        Condition condition = reentrantLock.newCondition();
        ConditionWait conditionWait = new ConditionWait(reentrantLock, condition);
        ConditionWait conditionWait2 = new ConditionWait(reentrantLock, condition);
        ConditionNotify conditionNotify = new ConditionNotify(reentrantLock, condition);
        conditionWait.start();
        conditionWait2.start();
        TimeUnit.SECONDS.sleep(2);
        conditionNotify.start();
    }

    public static class ConditionWait extends Thread {
        private Lock lock;

        private Condition condition;

        public ConditionWait(Lock lock, Condition condition) {
            this.lock = lock;
            this.condition = condition;
        }

        @Override
        public void run() {
            System.out.println("begin ConditionWait");
            try {
                lock.lock();
                //锁释放
                condition.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        }
    }


    public static class ConditionNotify extends Thread {

        private Lock lock;

        private Condition condition;

        public ConditionNotify(Lock lock, Condition condition) {
            this.lock = lock;
            this.condition = condition;
        }

        @Override
        public void run() {
            System.out.println("begin ConditionNotify");
            try {
                lock.lock();
                condition.signal();
                System.out.println("end ConditionNotify");
            } finally {
                lock.unlock();
            }
        }
    }

}
